<template>
  <div ref="containerRef" class="w-full h-full relative">
    <canvas ref="canvasRef" class="w-full h-full"></canvas>
  </div>
</template>

<script setup lang="ts">
import { ref, onMounted, onUnmounted } from 'vue'
import * as THREE from 'three'
import { OrbitControls } from 'three/addons/controls/OrbitControls.js';

const containerRef = ref<HTMLDivElement>()
const canvasRef = ref<HTMLCanvasElement>()

let scene: THREE.Scene
let camera: THREE.PerspectiveCamera
let renderer: THREE.WebGLRenderer
let animationId: number

// 创建场景
const createScene = () => {
  scene = new THREE.Scene()
  scene.background = new THREE.Color(0x0a0e27)
  
  // 添加雾效
  scene.fog = new THREE.Fog(0x0a0e27, 10, 100)
}

// 创建相机
const createCamera = () => {
  const aspect = window.innerWidth / window.innerHeight
  camera = new THREE.PerspectiveCamera(75, aspect, 0.1, 1000)
  camera.position.set(0, 15, 25)
  camera.lookAt(0, 0, 0)
}

// 创建渲染器
const createRenderer = () => {
  renderer = new THREE.WebGLRenderer({
    canvas: canvasRef.value!,
    antialias: true,
    alpha: true
  })
  renderer.setSize(window.innerWidth, window.innerHeight)
  renderer.setPixelRatio(window.devicePixelRatio)
  renderer.shadowMap.enabled = true
  renderer.shadowMap.type = THREE.PCFSoftShadowMap
}

// 创建灯光
const createLights = () => {
  // 环境光
  const ambientLight = new THREE.AmbientLight(0x404040, 0.3)
  scene.add(ambientLight)
  
  // 主光源
  const directionalLight = new THREE.DirectionalLight(0xffffff, 0.8)
  directionalLight.intensity = 2.0
  directionalLight.position.set(10, 5, 10)
  directionalLight.castShadow = true
  directionalLight.shadow.mapSize.width = 2048
  directionalLight.shadow.mapSize.height = 2048
  scene.add(directionalLight)
  
  // 点光源
  const pointLight = new THREE.PointLight(0x00ffff, 0.5, 50)
  pointLight.position.set(0, 10, 0)
  scene.add(pointLight)
}

// 创建建筑物
const createBuildings = () => {
  // 创建下方红色平台
  const redPlatformGeometry = new THREE.BoxGeometry(25, 4, 15)
  const redPlatformMaterial = new THREE.MeshLambertMaterial({ 
    color: 0x8d0000,
    transparent: true,
    opacity: 0.5
  })
  const redPlatform = new THREE.Mesh(redPlatformGeometry, redPlatformMaterial)
  redPlatform.position.set(0, 1, 0) // 位置在底部，y=1表示高度为2的一半
  redPlatform.castShadow = true
  redPlatform.receiveShadow = true
  scene.add(redPlatform)
  
  // 添加红色平台边框
  const redEdges = new THREE.EdgesGeometry(redPlatformGeometry)
  const redLineMaterial = new THREE.LineBasicMaterial({ color: 0x021338, opacity: 0.9, transparent: true })
  const redWireframe = new THREE.LineSegments(redEdges, redLineMaterial)
  redWireframe.position.copy(redPlatform.position)
  scene.add(redWireframe)
  
  // 创建上方蓝色平台，放置在红色平台的左后方
  const bluePlatformGeometry = new THREE.BoxGeometry(23, 3, 13)
  const bluePlatformMaterial = new THREE.MeshLambertMaterial({ 
    color: 0x013c9c,
    transparent: true,
    opacity: 0.65
  })
  const bluePlatform = new THREE.Mesh(bluePlatformGeometry, bluePlatformMaterial)
  bluePlatform.position.set(-2, 5, -3) // 位置在红色平台的左后方，y=4表示在红色平台上方
  bluePlatform.castShadow = true
  bluePlatform.receiveShadow = true
  scene.add(bluePlatform)
  
  // 添加蓝色平台边框
  const blueEdges = new THREE.EdgesGeometry(bluePlatformGeometry)
  const blueLineMaterial = new THREE.LineBasicMaterial({ color: 0xffffff, opacity: 0.1, transparent: true })
  const blueWireframe = new THREE.LineSegments(blueEdges, blueLineMaterial)
  blueWireframe.position.copy(bluePlatform.position)
  scene.add(blueWireframe)
}

// 创建设备节点
const createDeviceNodes = () => {
  const nodes = [
    // 主建筑上的节点
    { x: -3, y: 7, z: 2, color: 0x00ff00, status: 'normal' },
    { x: 3, y: 7, z: 2, color: 0xff0000, status: 'alert' },
    { x: 0, y: 7, z: -2, color: 0x00ff00, status: 'normal' },
    
    // 左侧建筑节点
    { x: -15, y: 4, z: -3, color: 0x00ff00, status: 'normal' },
    { x: -15, y: 4, z: -7, color: 0xffff00, status: 'warning' },
    
    // 右侧建筑节点
    { x: 15, y: 4, z: -3, color: 0x00ff00, status: 'normal' },
    { x: 15, y: 4, z: -7, color: 0x00ff00, status: 'normal' },
    
    // 后方建筑节点
    { x: -3, y: 5, z: -15, color: 0xff0000, status: 'alert' },
    { x: 3, y: 5, z: -15, color: 0x00ff00, status: 'normal' }
  ]
  
  nodes.forEach(node => {
    // 创建节点几何体
    const geometry = new THREE.SphereGeometry(0.3, 16, 16)
    const material = new THREE.MeshPhongMaterial({ 
      color: node.color,
      emissive: node.color,
      emissiveIntensity: 0.3
    })
    const mesh = new THREE.Mesh(geometry, material)
    mesh.position.set(node.x, node.y, node.z)
    scene.add(mesh)
    
    // 添加光晕效果
    const glowGeometry = new THREE.SphereGeometry(0.5, 16, 16)
    const glowMaterial = new THREE.MeshBasicMaterial({
      color: node.color,
      transparent: true,
      opacity: 0.2
    })
    const glow = new THREE.Mesh(glowGeometry, glowMaterial)
    glow.position.copy(mesh.position)
    scene.add(glow)
    
    // 添加状态指示器
    if (node.status === 'alert') {
      const indicatorGeometry = new THREE.ConeGeometry(0.2, 0.8, 8)
      const indicatorMaterial = new THREE.MeshBasicMaterial({ color: 0xff0000 })
      const indicator = new THREE.Mesh(indicatorGeometry, indicatorMaterial)
      indicator.position.set(node.x, node.y + 1, node.z)
      scene.add(indicator)
    }
  })
}

// 创建连接线
const createConnections = () => {
  const connections = [
    // 主建筑内部连接
    { from: { x: -3, y: 7, z: 2 }, to: { x: 3, y: 7, z: 2 } },
    { from: { x: 0, y: 7, z: -2 }, to: { x: -3, y: 7, z: 2 } },
    { from: { x: 0, y: 7, z: -2 }, to: { x: 3, y: 7, z: 2 } },
    
    // 跨建筑连接
    { from: { x: -15, y: 4, z: -3 }, to: { x: -3, y: 7, z: 2 } },
    { from: { x: 15, y: 4, z: -3 }, to: { x: 3, y: 7, z: 2 } },
    { from: { x: 0, y: 5, z: -15 }, to: { x: 0, y: 7, z: -2 } }
  ]
  
  connections.forEach(conn => {
    const points = []
    points.push(new THREE.Vector3(conn.from.x, conn.from.y, conn.from.z))
    
    // 添加中间控制点创建弧线
    const midX = (conn.from.x + conn.to.x) / 2
    const midY = Math.max(conn.from.y, conn.to.y) + 2
    const midZ = (conn.from.z + conn.to.z) / 2
    points.push(new THREE.Vector3(midX, midY, midZ))
    
    points.push(new THREE.Vector3(conn.to.x, conn.to.y, conn.to.z))
    
    const curve = new THREE.CatmullRomCurve3(points)
    const tubeGeometry = new THREE.TubeGeometry(curve, 64, 0.05, 8, false)
    const tubeMaterial = new THREE.MeshBasicMaterial({ 
      color: 0x00ffff,
      transparent: true,
      opacity: 0.7
    })
    const tube = new THREE.Mesh(tubeGeometry, tubeMaterial)
    scene.add(tube)
  })
}

// 创建粒子效果
const createParticles = () => {
  const particleCount = 200
  const positions = new Float32Array(particleCount * 3)
  
  for (let i = 0; i < particleCount; i++) {
    positions[i * 3] = (Math.random() - 0.5) * 50
    positions[i * 3 + 1] = Math.random() * 20
    positions[i * 3 + 2] = (Math.random() - 0.5) * 50
  }
  
  const geometry = new THREE.BufferGeometry()
  geometry.setAttribute('position', new THREE.BufferAttribute(positions, 3))
  
  const material = new THREE.PointsMaterial({
    color: 0x00ffff,
    size: 0.1,
    transparent: true,
    opacity: 0.6
  })
  
  const particles = new THREE.Points(geometry, material)
  scene.add(particles)
  
  return particles
}

// 动画循环
const animate = () => {
  animationId = requestAnimationFrame(animate)
  
  // 旋转相机
  // const time = Date.now() * 0.0005
  // camera.position.x = Math.cos(time) * 30
  // camera.position.z = Math.sin(time) * 30
  // camera.lookAt(0, 5, 0)
  
  renderer.render(scene, camera)
}

// 处理窗口大小变化
const handleResize = () => {
  const width = window.innerWidth
  const height = window.innerHeight
  
  camera.aspect = width / height
  camera.updateProjectionMatrix()
  
  renderer.setSize(width, height)
}

// 创建网格平面
const createGridPlane = () => {
  // 创建一个大型网格平面
  const gridSize = 150; // 网格大小
  const gridDivisions = 50; // 网格分割数量
  const gridHelper = new THREE.GridHelper(gridSize, gridDivisions, 0x005bb8, 0x005bb8);
  gridHelper.position.y = 0; // 放置在底部
  gridHelper.material.opacity = 0.2;
  gridHelper.material.transparent = true;
  scene.add(gridHelper);
}

// 初始化
const init = () => {
  createScene()
  createCamera()
  createRenderer()
  createLights()
  createGridPlane() // 添加网格平面
  createBuildings()
  // createDeviceNodes()
  // createConnections()
  // createParticles()
  
  animate()

  const axesHelper = new THREE.AxesHelper(150);
  scene.add(axesHelper);
  // 设置相机控件轨道控制器OrbitControls
  const controls = new OrbitControls(camera, renderer.domElement);
  // 如果OrbitControls改变了相机参数，重新调用渲染器渲染三维场景
  controls.addEventListener('change', function () {
      renderer.render(scene, camera); //执行渲染操作
  });//监听鼠标、键盘事件
  
  window.addEventListener('resize', handleResize)
}

// 清理
const cleanup = () => {
  if (animationId) {
    cancelAnimationFrame(animationId)
  }
  
  window.removeEventListener('resize', handleResize)
  
  if (renderer) {
    renderer.dispose()
  }
}

onMounted(() => {
  init()
})

onUnmounted(() => {
  cleanup()
})
</script>

<style scoped>
/* 组件样式 */
</style>